package top.cyuw.subjectsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import top.cyuw.subjectsystem.constant.RoleConstants;
import top.cyuw.subjectsystem.dto.PagingParamDto;
import top.cyuw.subjectsystem.dto.user.UserCreateRequest;
import top.cyuw.subjectsystem.dto.user.UserEditRequest;
import top.cyuw.subjectsystem.dto.user.UserImportDto;
import top.cyuw.subjectsystem.dto.user.UserLoginRequest;
import top.cyuw.subjectsystem.entity.Depart;
import top.cyuw.subjectsystem.entity.User;
import top.cyuw.subjectsystem.exception.ServiceException;
import top.cyuw.subjectsystem.mapper.UserMapper;
import top.cyuw.subjectsystem.service.DepartService;
import top.cyuw.subjectsystem.service.UserService;
import top.cyuw.subjectsystem.util.JwtTokenUtils;
import top.cyuw.subjectsystem.util.MapperUtils;
import top.cyuw.subjectsystem.vo.ImportResultVo;
import top.cyuw.subjectsystem.vo.PagingVo;
import top.cyuw.subjectsystem.vo.user.UserDetailVo;
import top.cyuw.subjectsystem.vo.user.UserVo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    DepartService departService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public UserVo login(UserLoginRequest request) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername());

        User user = super.getOne(wrapper, false);
        if (user == null) {
            throw new ServiceException(400, "用户不存在");
        }
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new ServiceException(400, "密码错误");
        }
        UserVo vo = MapperUtils.map(user, UserVo.class);
        if (StringUtils.isEmpty(user.getRole())) {
            user.setRole(RoleConstants.USER);
        }
        vo.setToken(JwtTokenUtils.createToken(user.getId(), user.getRole()));
        return vo;
    }

    @Override
    public Boolean create(UserCreateRequest request) {
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setRole(request.getRole());
        user.setDepartId(request.getDepartId());
        Date now = new Date();
        user.setCreateTime(now);
        user.setUpdateTime(now);
        return super.save(user);
    }

    @Override
    public Boolean edit(UserEditRequest request) {
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(User::getId, request.getId());
        if (StringUtils.isNotEmpty(request.getPassword())) {
            wrapper.set(User::getPassword, passwordEncoder.encode(request.getPassword()));
        }
        if (StringUtils.isNotEmpty(request.getRole())) {
            wrapper.set(User::getRole, request.getRole());
        }
        wrapper.set(User::getDepartId, request.getDepartId());
        wrapper.set(User::getUpdateTime, new Date());
        return super.update(wrapper);
    }

    @Override
    public PagingVo<UserDetailVo> search(PagingParamDto<String> request) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(User::getUsername, request.getParam());
        Page<User> page = super.page(
                new Page<>(request.getPageNum(), request.getPageSize()), wrapper);
        return PagingVo.of(MapperUtils.mapList(page.getRecords(), UserDetailVo.class),
                page.getTotal(), page.getCurrent(), page.getPages());
    }

    @Override
    public Boolean delete(Integer id) {
        return super.removeById(id);
    }

    @Override
    public ImportResultVo importFromExcel(List<UserImportDto> list) {
        ImportResultVo resultVo = ImportResultVo.create();
        List<User> users = new ArrayList<>(list.size());
        String password = passwordEncoder.encode("123456");
        Date now = new Date();
        for (UserImportDto dto : list) {
            if (StringUtils.isEmpty(dto.getUsername()) || StringUtils.isEmpty(dto.getRole()) || StringUtils.isEmpty(dto.getDepart())) {
                continue;
            }
            Depart depart = departService.getOne(new LambdaQueryWrapper<Depart>().eq(Depart::getName, dto.getDepart()), false);
            if (depart == null) {
                resultVo.addError("部门'" + dto.getDepart() + "'不存在！");
                continue;
            }
            User repeatUser = super.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, dto.getUsername()), false);
            if (repeatUser != null) {
                resultVo.addError("用户'" + dto.getDepart() + "'已存在！");
                continue;
            }
            User user = new User();
            user.setUsername(dto.getUsername());
            user.setPassword(password);
            user.setRole("管理员".equals(dto.getRole()) ? "ADMIN" : "USER");
            user.setDepartId(depart.getId());
            user.setUpdateTime(now);
            user.setCreateTime(now);
            users.add(user);
            resultVo.incSuccess();
        }
        super.saveBatch(users);
        return resultVo;
    }


}
